package jxtend.processor.eclipse.jdt.dom;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import org.eclipse.jdt.core.dom.ASTNode;

public abstract class AbstractJDTDomASTVisitorMethodInterceptor implements MethodInterceptor {

	@Override
	public final Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
		if (!method.getDeclaringClass().equals(obj.getClass().getSuperclass())
				|| (!method.getName().equals("visit") && !method.getName().equals("endVisit"))
				|| args[0].getClass().getSimpleName().startsWith("Javadoc")) {
			return proxy.invokeSuper(obj, args);
		}

		ASTNode node = (ASTNode) args[0];

		if (method.getName().equals("visit")) {
			return interceptVisit(node);
		} else {
			assert method.getName().equals("endVisit");

			interceptEndVisit(node);
			// Always return null. Returned value is not relevant since 'endVisit' methods have return type of 'void'
			return null;
		}
	}

	protected abstract boolean interceptVisit(ASTNode node);

	protected abstract void interceptEndVisit(ASTNode node);

}
